﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using OrionFlamesMn;

namespace OrionFlamesCSharpGui
{
	public class XFormGUI
	{
		public XFormGUI(XFormMn xform, IfsAnimatorMn animator, uint index, int groupBoxWidth)
		{
			m_XForm = xform;
			m_IfsAnimator = animator;
			m_XformIndex = index;

			//Create our controls to add to the group box below.
			m_LblXFormWeight.Text = "Weight:";
			m_LblXFormWeight.AutoSize = true;
			m_LblXFormWeightVal.Text = String.Format("{0}", m_XForm.Weight);
			m_LblXFormWeightVal.AutoSize = true;
			
			m_LblXFormNonlinearWeight.Text = "Nonlinear Weight:";
			m_LblXFormNonlinearWeight.AutoSize = true;
			m_LblXFormNonlinearWeightVal.Text = String.Format("{0}", m_XForm.NonlinearWeight);
			m_LblXFormNonlinearWeightVal.AutoSize = true;

			m_LblXx.Text = "X.x:";
			m_LblXx.AutoSize = true;
			m_LblXxVal.Text = String.Format("{0}", m_XForm.X.X);
			m_LblXxVal.AutoSize = true;

			m_LblXy.Text = "X.y:";
			m_LblXy.AutoSize = true;
			m_LblXyVal.Text = String.Format("{0}", m_XForm.X.Y);
			m_LblXyVal.AutoSize = true;

			m_LblYx.Text = "Y.x:";
			m_LblYx.AutoSize = true;
			m_LblYxVal.Text = String.Format("{0}", m_XForm.Y.X);
			m_LblYxVal.AutoSize = true;

			m_LblYy.Text = "Y.y:";
			m_LblYy.AutoSize = true;
			m_LblYyVal.Text = String.Format("{0}", m_XForm.Y.Y);
			m_LblYyVal.AutoSize = true;
			
			m_LblOx.Text = "O.x:";
			m_LblOx.AutoSize = true;
			m_LblOxVal.Text = String.Format("{0}", m_XForm.O.X);
			m_LblOxVal.AutoSize = true;

			m_LblOy.Text = "O.y:";
			m_LblOy.AutoSize = true;
			m_LblOyVal.Text = String.Format("{0}", m_XForm.O.Y);
			m_LblOyVal.AutoSize = true;

			m_LblRotMult.Text = "Rot mult:";
			m_LblRotMult.AutoSize = true;
			m_LblRotMultVal.Text = "0";
			m_LblRotMultVal.AutoSize = true;

			m_GroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
			| System.Windows.Forms.AnchorStyles.Right)));
			m_GroupBox.AutoSize = false;
			m_GroupBox.Name = "grpPresetParams";
			m_GroupBox.Margin = new Padding(5);
			m_GroupBox.Size = new System.Drawing.Size(groupBoxWidth, 50);
			m_GroupBox.TabIndex = 6;
			m_GroupBox.TabStop = false;
			m_GroupBox.Text = m_XForm.VariationName();

			m_TrkWeight = CreateTrackBar("trkWeight", 10, 1, 0, 100, new EventHandler(m_TrkWeight_ValueChanged));
			m_TrkNonlinearWeight = CreateTrackBar("trkNonlinearWeight", 10, 1, 0, 100, new EventHandler(m_TrkNonlinearWeight_ValueChanged));
			m_TrkXx = CreateTrackBar("trkXx", 10, 1, -500, 500, new EventHandler(m_TrkXx_ValueChanged));
			m_TrkXy = CreateTrackBar("trkXy", 10, 1, -500, 500, new EventHandler(m_TrkXy_ValueChanged));
			m_TrkYx = CreateTrackBar("trkYx", 10, 1, -500, 500, new EventHandler(m_TrkYx_ValueChanged));
			m_TrkYy = CreateTrackBar("trkYy", 10, 1, -500, 500, new EventHandler(m_TrkYy_ValueChanged));
			m_TrkOx = CreateTrackBar("trkOx", 10, 1, -500, 500, new EventHandler(m_TrkOx_ValueChanged));
			m_TrkOy = CreateTrackBar("trkOy", 10, 1, -500, 500, new EventHandler(m_TrkOy_ValueChanged));
			m_TrkRotMult = CreateTrackBar("trkRotMult", 10, 1, 0, 1000, new EventHandler(m_TrkRotMult_ValueChanged));

			//Add all controls.
			m_GroupBox.Controls.Add(m_LblXFormWeight);
			m_GroupBox.Controls.Add(m_LblXFormWeightVal);
			m_GroupBox.Controls.Add(m_TrkWeight);
			m_GroupBox.Controls.Add(m_TrkNonlinearWeight);
			m_GroupBox.Controls.Add(m_LblXFormNonlinearWeight);
			m_GroupBox.Controls.Add(m_LblXFormNonlinearWeightVal);
			m_GroupBox.Controls.Add(m_LblXx);
			m_GroupBox.Controls.Add(m_LblXxVal);
			m_GroupBox.Controls.Add(m_TrkXx);
			m_GroupBox.Controls.Add(m_LblXy);
			m_GroupBox.Controls.Add(m_LblXyVal);
			m_GroupBox.Controls.Add(m_TrkXy);
			m_GroupBox.Controls.Add(m_LblYx);
			m_GroupBox.Controls.Add(m_LblYxVal);
			m_GroupBox.Controls.Add(m_TrkYx);
			m_GroupBox.Controls.Add(m_LblYy);
			m_GroupBox.Controls.Add(m_LblYyVal);
			m_GroupBox.Controls.Add(m_TrkYy);
			m_GroupBox.Controls.Add(m_LblOx);
			m_GroupBox.Controls.Add(m_LblOxVal);
			m_GroupBox.Controls.Add(m_TrkOx);
			m_GroupBox.Controls.Add(m_LblOy);
			m_GroupBox.Controls.Add(m_LblOyVal);
			m_GroupBox.Controls.Add(m_TrkOy);
			m_GroupBox.Controls.Add(m_LblRotMult);
			m_GroupBox.Controls.Add(m_LblRotMultVal);
			m_GroupBox.Controls.Add(m_TrkRotMult);

			//Label column.
			m_LabelColumn.Add(m_LblXFormWeight);
			m_LabelColumn.Add(m_LblXFormNonlinearWeight);
			m_LabelColumn.Add(m_LblXx);
			m_LabelColumn.Add(m_LblXy);
			m_LabelColumn.Add(m_LblYx);
			m_LabelColumn.Add(m_LblYy);
			m_LabelColumn.Add(m_LblOx);
			m_LabelColumn.Add(m_LblOy);
			m_LabelColumn.Add(m_LblRotMult);

			//Trackbar column.
			m_TrackbarColumn.Add(m_TrkWeight);
			m_TrackbarColumn.Add(m_TrkNonlinearWeight);
			m_TrackbarColumn.Add(m_TrkXx);
			m_TrackbarColumn.Add(m_TrkXy);
			m_TrackbarColumn.Add(m_TrkYx);
			m_TrackbarColumn.Add(m_TrkYy);
			m_TrackbarColumn.Add(m_TrkOx);
			m_TrackbarColumn.Add(m_TrkOy);
			m_TrackbarColumn.Add(m_TrkRotMult);

			//Label value column.
			m_LabelValueColumn.Add(m_LblXFormWeightVal);
			m_LabelValueColumn.Add(m_LblXFormNonlinearWeightVal);
			m_LabelValueColumn.Add(m_LblXxVal);
			m_LabelValueColumn.Add(m_LblXyVal);
			m_LabelValueColumn.Add(m_LblYxVal);
			m_LabelValueColumn.Add(m_LblYyVal);
			m_LabelValueColumn.Add(m_LblOxVal);
			m_LabelValueColumn.Add(m_LblOyVal);
			m_LabelValueColumn.Add(m_LblRotMultVal);

			//Assign track values.
			m_TrkWeight.Value = (int)(m_XForm.Weight * (float)m_TrkWeight.Maximum);
			m_TrkNonlinearWeight.Value = (int)((m_XForm.NonlinearWeight * (float)m_TrkNonlinearWeight.Maximum) / 5.0f);
			m_TrkXx.Value = (int)(m_XForm.X.X * 100.0f);
			m_TrkXy.Value = (int)(m_XForm.X.Y * 100.0f);
			m_TrkYx.Value = (int)(m_XForm.Y.X * 100.0f);
			m_TrkYy.Value = (int)(m_XForm.Y.Y * 100.0f);
			m_TrkOx.Value = (int)(m_XForm.O.X * 100.0f);
			m_TrkOy.Value = (int)(m_XForm.O.Y * 100.0f);
			m_TrkRotMult.Value = (int)(m_IfsAnimator.XformRotationMult(m_XformIndex) * 100.0f);

			int gap = 10;
			int offset = 19;

			for (int i = 0; i < m_LabelColumn.Count; i++)
			{
				m_LabelColumn[i].Left = 3;
				m_LabelColumn[i].Height = 13;
				m_LabelColumn[i].Top = offset + (i * (m_LabelColumn[i].Height + gap));//Use the height of this label, since all label heights are the same.
			}

			gap = 6;
			offset = 19;

			for (int i = 0; i < m_TrackbarColumn.Count; i++)
			{
				m_TrackbarColumn[i].Left = 100;
				m_TrackbarColumn[i].Size = new System.Drawing.Size(118, m_TrackbarColumn[i].Size.Height);//Keep height the same but change the width.
				m_TrackbarColumn[i].Top = offset + (i * (m_TrackbarColumn[i].Height + gap));
			}

			gap = 10;
			offset = 19;

			for (int i = 0; i < m_LabelValueColumn.Count; i++)
			{
				m_LabelValueColumn[i].Left = m_TrackbarColumn[i].Left + m_TrackbarColumn[i].Width + 6;//Position it to the right of the tackbar.
				m_LabelValueColumn[i].Height = 13;
				m_LabelValueColumn[i].Top = offset + (i * (m_LabelValueColumn[i].Height + gap));//Use the height of this label, since all label heights are the same.
			}

			//Last, set the height of the GroupBox.
			m_GroupBox.Height = m_TrackbarColumn[m_TrackbarColumn.Count - 1].Bottom + 3;// +m_TrackbarColumn[m_TrackbarColumn.Count].Height;
		}

		private void m_TrkWeight_ValueChanged(object sender, EventArgs e)
		{
			Weight = ((float)m_TrkWeight.Value / (float)m_TrkWeight.Maximum);//Might end up with some rounding on first assignment.
		}

		private void m_TrkNonlinearWeight_ValueChanged(object sender, EventArgs e)
		{
			NonlinearWeight = ((float)m_TrkNonlinearWeight.Value / (float)m_TrkNonlinearWeight.Maximum) * 5.0f;//Might end up with some rounding on first assignment.
		}

		private void m_TrkXx_ValueChanged(object sender, EventArgs e)
		{
			Xx = (float)m_TrkXx.Value / 100.0f;
		}

		private void m_TrkXy_ValueChanged(object sender, EventArgs e)
		{
			Xy = (float)m_TrkXy.Value / 100.0f;
		}

		private void m_TrkYx_ValueChanged(object sender, EventArgs e)
		{
			Yx = (float)m_TrkYx.Value / 100.0f;
		}

		private void m_TrkYy_ValueChanged(object sender, EventArgs e)
		{
			Yy = (float)m_TrkYy.Value / 100.0f;
		}

		private void m_TrkOx_ValueChanged(object sender, EventArgs e)
		{
			Ox = (float)m_TrkOx.Value / 100.0f;
		}

		private void m_TrkOy_ValueChanged(object sender, EventArgs e)
		{
			Oy = (float)m_TrkOy.Value / 100.0f;
		}

		private void m_TrkRotMult_ValueChanged(object sender, EventArgs e)
		{
			RotMult = (float)m_TrkRotMult.Value / 100.0f;
		}

		private TrackBar CreateTrackBar(String name, int largeChange, int smallChange, int min, int max, EventHandler changeHandler)
		{
			TrackBar trackBar = new TrackBar();

			trackBar.AutoSize = false;
			trackBar.LargeChange = largeChange;
			trackBar.Location = new System.Drawing.Point(100, 151);
			trackBar.Maximum = max;
			trackBar.Minimum = min;
			trackBar.Name = name;
			trackBar.Size = new System.Drawing.Size(118, 17);
			//trackBar.TabIndex = 12;
			trackBar.TickFrequency = 20;
			trackBar.Value = 1;
			trackBar.SmallChange = smallChange;
			trackBar.Scroll += new EventHandler(changeHandler);//Set them both to the same event.
			trackBar.ValueChanged += new EventHandler(changeHandler);

			return trackBar;
		}

		public GroupBox GroupBox
		{
			get { return m_GroupBox; }
		}

		public float Weight
		{
			get { return m_XForm.Weight; }

			set
			{
				m_XForm.Weight = value;
				m_LblXFormWeightVal.Text = m_XForm.Weight.ToString("F2");
			}
		}

		public float NonlinearWeight
		{
			get { return m_XForm.NonlinearWeight; }

			set
			{
				m_XForm.NonlinearWeight = value;
				m_LblXFormNonlinearWeightVal.Text = m_XForm.NonlinearWeight.ToString("F2");
			}
		}

		public float Xx
		{
			get { return m_XForm.X.X; }

			set
			{
				m_XForm.X.X = value;
				m_LblXxVal.Text = m_XForm.X.X.ToString("F2");
			}
		}

		public float Xy
		{
			get { return m_XForm.X.Y; }

			set
			{
				m_XForm.X.Y = value;
				m_LblXyVal.Text = m_XForm.X.Y.ToString("F2");
			}
		}

		public float Yx
		{
			get { return m_XForm.Y.X; }

			set
			{
				m_XForm.Y.X = value;
				m_LblYxVal.Text = m_XForm.Y.X.ToString("F2");
			}
		}

		public float Yy
		{
			get { return m_XForm.Y.Y; }

			set
			{
				m_XForm.Y.Y = value;
				m_LblYyVal.Text = m_XForm.Y.Y.ToString("F2");
			}
		}

		public float Ox
		{
			get { return m_XForm.O.X; }

			set
			{
				m_XForm.O.X = value;
				m_LblOxVal.Text = m_XForm.O.X.ToString("F2");
			}
		}

		public float Oy
		{
			get { return m_XForm.O.Y; }

			set
			{
				m_XForm.O.Y = value;
				m_LblOyVal.Text = m_XForm.O.Y.ToString("F2");
			}
		}

		public float RotMult
		{
			get { return m_IfsAnimator.XformRotationMult(m_XformIndex); }

			set
			{
				m_IfsAnimator.XformRotationMult(m_XformIndex, value);
				m_LblRotMultVal.Text = m_IfsAnimator.XformRotationMult(m_XformIndex).ToString("F2");
			}
		}

		private XFormMn m_XForm;
		private GroupBox m_GroupBox = new GroupBox();
		private uint m_XformIndex;

		//Weight.
		private Label m_LblXFormWeight = new Label();
		private Label m_LblXFormWeightVal = new Label();
		private TrackBar m_TrkWeight;

		//Nonlinear Weight.
		private Label m_LblXFormNonlinearWeight = new Label();
		private Label m_LblXFormNonlinearWeightVal = new Label();
		private TrackBar m_TrkNonlinearWeight;

		//X.x.
		private Label m_LblXx = new Label();
		private Label m_LblXxVal = new Label();
		private TrackBar m_TrkXx;

		//X.y.
		private Label m_LblXy = new Label();
		private Label m_LblXyVal = new Label();
		private TrackBar m_TrkXy;

		//Y.x.
		private Label m_LblYx = new Label();
		private Label m_LblYxVal = new Label();
		private TrackBar m_TrkYx;

		//Y.y.
		private Label m_LblYy = new Label();
		private Label m_LblYyVal = new Label();
		private TrackBar m_TrkYy;

		//O.x.
		private Label m_LblOx = new Label();
		private Label m_LblOxVal = new Label();
		private TrackBar m_TrkOx;

		//O.y.
		private Label m_LblOy = new Label();
		private Label m_LblOyVal = new Label();
		private TrackBar m_TrkOy;

		//Xform rotation multiplier.
		private Label m_LblRotMult = new Label();
		private Label m_LblRotMultVal = new Label();
		private TrackBar m_TrkRotMult;

		private List<Control> m_LabelColumn = new List<Control>();
		private List<Control> m_LabelValueColumn = new List<Control>();
		private List<Control> m_TrackbarColumn = new List<Control>();
		private IfsAnimatorMn m_IfsAnimator;
	}
}
